#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "tm1637.h"
#include "tm1638.h"
#include "keyBoard.h"
#include "symbols.h"
#include <esp_timer.h>
#include <string>

// 定义tm1637的引脚
// 定义DIO和CLK引脚
#define PIN_DIO GPIO_NUM_19
#define PIN_CLK GPIO_NUM_18
// 定义数码管类型
#define TUBETYPE_4SEG true

// 定义tm1638的引脚
#define TM1638_PIN_DIO GPIO_NUM_23
#define TM1638_PIN_CLK GPIO_NUM_22
#define TM1638_PIN_STB GPIO_NUM_21

// 定义共阳极tm1638的引脚，和tm1637不能同时进行测试，因为二者的clk和dio引脚相同。
#define TM1638_PIN_DIO_Anode GPIO_NUM_19
#define TM1638_PIN_CLK_Anode GPIO_NUM_18
#define TM1638_PIN_STB_Anode GPIO_NUM_5

// TM1637 myTM1637;
// TM1637模块测试任务
void task1(void *arg)
{
    TickType_t start_time = xTaskGetTickCount();
    vTaskDelay(pdMS_TO_TICKS(10));
    // ets_delay_us(1);
    uint16_t pass_time = xTaskGetTickCount() - start_time;
    ESP_LOGD("DEBUG", "初始化前耗时%d ms", pass_time);

    TM1637 myTM1637(PIN_CLK, PIN_DIO, TUBETYPE_4SEG);

    while (1)
    {

        // 测试自动地址模式显示
        myTM1637.disp_string("PLAY", false);
        vTaskDelay(pdMS_TO_TICKS(1000));
        myTM1637.disp_clear();
        myTM1637.disp_string("OK", false);
        vTaskDelay(pdMS_TO_TICKS(1000));
        myTM1637.disp_string("OK", true);
        vTaskDelay(pdMS_TO_TICKS(1000));
        myTM1637.disp_string("THANK", false);
        vTaskDelay(pdMS_TO_TICKS(1000));
        myTM1637.disp_string("Good", false);
        vTaskDelay(pdMS_TO_TICKS(1000));
        myTM1637.disp_clear();

        // 测试字符串从数码管的右侧平滑进入显示
        // myTM1637.disp_slide("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");

        // 测试显示数字
        myTM1637.disp_num(314159, true);
        vTaskDelay(pdMS_TO_TICKS(1000));
        myTM1637.disp_num(3.14159f, true);
        vTaskDelay(pdMS_TO_TICKS(1000));

        // 测试显示浮点数
        myTM1637.disp_num_with_dot(0.1234, false);
        vTaskDelay(pdMS_TO_TICKS(1000));
        myTM1637.disp_num_with_dot(1234.56789, true);
        vTaskDelay(pdMS_TO_TICKS(1000));

        // 十六进制
        int value = 164;
        char hex[4] = {0};
        snprintf(hex, sizeof(hex), "%X", value);
        myTM1637.disp_string(hex, false);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

/*
// TM1638共阴极模块测试任务
void task2(void *param)
{
    // 该映射必须根据手里面的具体模块布局来手动修改.
    // 从左到右->0..7
    segLayout_t segment_idx = {.idx = {0, 1, 2, 3, 4, 5, 6, 7}};

    // 共阴极数码管
    TM1638 myTM1638(TM1638_PIN_STB, TM1638_PIN_CLK, TM1638_PIN_DIO, 1, &segment_idx);
    // myTM1638.startKeyTask(3, 1);
    key_event_t ev;
    uint8_t num = 0;

    while (1)
    {
        // 使用键盘事件队列处理按键
        // if (myTM1638.getKeyEvent(&ev) == true)
        {
            ESP_LOGI("task2,Receive", "type = %s", (ev.type == KEY_EV_PRESS)? "press": (ev.type == KEY_EV_LONG)? "long": (ev.type == KEY_EV_RELEASE)?"release":(ev.type == KEY_EV_REPEAT)?"repeat":"init");
            if (ev.type == KEY_EV_PRESS)
            {
                if (ev.key_id == 0)
                    num = (num + 1) % 10;
                if (ev.key_id == 4)
                    num = (num + 9) % 10;
                myTM1638.dispNum(ev.key_id);
            }
        }
        vTaskDelay(pdMS_TO_TICKS(100));
    }
}

// TM1638共阳极模块测试任务
void task3(void *param)
{
    // TM1638共阳极模块对象
    // 该映射必须根据手里面的具体模块布局来手动修改.
    // 从左到右-> 7..0。
    const segLayout_t segment_idx = {.idx = {7, 6, 5, 4, 3, 2, 1, 0}};
    TM1638 myTM1638(TM1638_PIN_STB_Anode, TM1638_PIN_CLK_Anode, TM1638_PIN_DIO_Anode, 1, &segment_idx, true);
    // myTM1638.startKeyTask(4, 1);

    key_event_t ev;
    uint8_t num = 0;
    while (1)
    {
         // 使用键盘事件队列处理按键
        // if (myTM1638.getKeyEvent(&ev) == true)
        {
            ESP_LOGI("task3,Receive", "type = %s", (ev.type == KEY_EV_PRESS)? "press": (ev.type == KEY_EV_LONG)? "long": (ev.type == KEY_EV_RELEASE)?"release":(ev.type == KEY_EV_REPEAT)?"repeat":"init");
            if (ev.type == KEY_EV_PRESS)
            {
                if (ev.key_id == 0)
                    num = (num + 1) % 10;
                if (ev.key_id == 4)
                    num = (num + 9) % 10;
                myTM1638.dispNum(ev.key_id);
            }
        }
        vTaskDelay(pdMS_TO_TICKS(100));
    }
}
*/

// 使用全局化的tm1638实例
// TM1638共阳极模块对象
// 该映射必须根据手里面的具体模块布局来手动修改.
// 从左到右-> 7..0。
const segLayout_t segment_idx = {.idx = {7, 6, 5, 4, 3, 2, 1, 0}};
TM1638 myTM1638(TM1638_PIN_STB_Anode, TM1638_PIN_CLK_Anode, TM1638_PIN_DIO_Anode, 1, &segment_idx, true);

void onKey(key_event_t ev)
{
    ESP_LOGI("onKey", "type = %s", (ev.type == KEY_EV_PRESS) ? "press" : (ev.type == KEY_EV_LONG)  ? "long"
                                                                     : (ev.type == KEY_EV_RELEASE) ? "release"
                                                                     : (ev.type == KEY_EV_REPEAT)  ? "repeat"
                                                                                                   : "init");
    ESP_LOGI("onKey", "key_id = %d", ev.key_id);
    // printf("raw = %08lX, raise = %08lX, fall = %08lX\n", raw, raisePulse, fallPulse);
    // 显示对应的按键值的16进制数。
    static int num = 0;
    if (ev.type == KEY_EV_PRESS)
        num++;
    if (ev.key_id == 5 && ev.type == KEY_EV_LONG)
        num++;
    if (ev.key_id == 1 && ev.type == KEY_EV_LONG)
        num--;
    myTM1638.clear();
    myTM1638.dispNum(num);
    // myTM1638.dispString(str);
}

void keyBoardTask(void *param)
{
    KeyBoard myKey(myTM1638);
    myKey.attach(onKey);

    while (1)
    {
        myKey.scan();
        vTaskDelay(pdMS_TO_TICKS(100));
    }
}

extern "C" void app_main()
{

    xTaskCreatePinnedToCore(keyBoardTask, "keyBoardTask", 4096, NULL, 4, NULL, 1);
    // xTaskCreatePinnedToCore(task2, "task2", 4096, NULL, 5, NULL, 1);
}